import React, { Component } from 'react'
import { v4 } from 'uuid'

import styles from './css/styles.css'

let baseIndex = 12

class Toast extends Component {
  constructor(props) {
    super(props)

    this.state = {
      toasts: [],
      zindex: baseIndex,
    }

    this._add = this._add.bind(this)
    this._remove = this._remove.bind(this)
    this._clearOnExpire = this._clearOnExpire.bind(this)
    this._renderToasts = this._renderToasts.bind(this)
    this._renderToastItem = this._renderToastItem.bind(this)
  }

  componentWillUnmount() {
  
    const toasts = this.state.toasts
    for (var i = 0; i < toasts.length; i++) {
      clearTimeout(this[toasts[i].id])
    }
  }
  
  _add(msg = '提示不能为空', {expire = 5000, type = 'default', position = 'top', style={}}) {
    const zindex = this.state.zindex + 1
    const message = {
      id: v4(),
      msg: msg,
      type: type,
      position: position,
      zindex: zindex,
      style: style,
      expire: expire, 
    }
    this.setState({
      toasts: this.state.toasts.concat(message),
      zindex: zindex,
    }, () => this._clearOnExpire(message.id, expire))

    return message.id
  }

  _remove(id) {
    if(!this[id]) return
    if(this.state.toasts.length === 1) {
      this.setState({
        zindex: baseIndex,
      })
    }
    clearTimeout(this[id])
    delete this[id]
    this.setState({
      toasts: this.state.toasts.filter((item) => item.id !== id)
    })
  }

  _clearOnExpire(id, expire) {
    this[id] = setTimeout(() => {
      this._remove(id)
    }, expire)
  }
  
  _renderToastItem(item, index) {
    return (
      <div 
        key={item.id}
        style={{
          ...item.style,
          zIndex: item.zindex
        }}
        className={`${styles.toast} ${styles[item.type]} ${styles[item.position]}`}
        onClick={() => this._remove(item.id)}
      >
        {item.msg}
      </div>
    )
  }

  _renderToasts() {
    return this.state.toasts.map((item, index) => this._renderToastItem(item, index))
  }

  render() {
    return (
      <div>
        { this._renderToasts() }
      </div>
    )
  }
}

export default Toast